package com.ruoyi.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zengqingfa
 * @date 2019/11/4 17:08
 * @description
 * @email zengqingfa_java@163.com
 */
@Component
public class AppUtil implements ApplicationContextAware {
    protected static final Logger logger = LoggerFactory.getLogger(AppUtil.class);

    public AppUtil() {
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {
        AppUtil.Inner.setContext(context);
    }

    public static void setOnlineContext(ApplicationContext context) throws BeansException {
        AppUtil.Inner.setContext(context);
    }

    public static ApplicationContext getApplicaitonContext() {
        return AppUtil.Inner.getContext();
    }

    public static void refreshContext() {
        ((ConfigurableApplicationContext)AppUtil.Inner.getContext()).refresh();
    }

    public static void registerBean(Class<?>... var0) {
        DefaultListableBeanFactory var1 = (DefaultListableBeanFactory)((ConfigurableApplicationContext)AppUtil.Inner.getContext()).getBeanFactory();
        int var2 = (var0 = var0).length;

        for(int var3 = 0; var3 < var2; ++var3) {
            Class var4;
            BeanDefinitionBuilder var5 = BeanDefinitionBuilder.genericBeanDefinition(var4 = var0[var3]);
            String var6 = StringUtil.lowerFirst(var4.getSimpleName());
            var1.registerBeanDefinition(var6, var5.getBeanDefinition());
            logger.debug("register class {} {}.", var4.getName(), "success");
        }

    }

    public static String getProperty(String var0, String var1) {
        PropertyPlaceholderConfigurerExt var2;
        if (BeanUtils.isEmpty(var2 = (PropertyPlaceholderConfigurerExt)getBean("corePlaceHolder"))) {
            return var1;
        } else {
            return StringUtil.isEmpty(var0 = var2.getValue(var0)) ? var1 : var0.trim();
        }
    }

    public static void scanBeans(String... var0) {
        BeanDefinitionRegistry var1 = (BeanDefinitionRegistry)((ConfigurableApplicationContext)AppUtil.Inner.getContext()).getBeanFactory();
        int var2 = (var0 = var0).length;

        for(int var3 = 0; var3 < var2; ++var3) {
            String var4 = var0[var3];
            logger.debug("before bean count is {} .", var1.getBeanDefinitionCount());
            int var5 = (new ClassPathBeanDefinitionScanner(var1)).scan(new String[]{var4});
            logger.debug("after bean count is {} .", var1.getBeanDefinitionCount());
            logger.debug("scan {} beans from package {} .", var5, var4);
        }

    }

    public static List<String> scanPackages(String var0) throws IllegalArgumentException {
        PathMatchingResourcePatternResolver var1 = new PathMatchingResourcePatternResolver();
        CachingMetadataReaderFactory var2 = new CachingMetadataReaderFactory(var1);
        ArrayList var3 = new ArrayList();
        String[] var4 = var0.split(",");

        try {
            for(int var5 = 0; var5 < var4.length; ++var5) {
                String var6 = var4[var5].replace('.', '/');
                var6 = "classpath*:/" + var6 + "/**/*.class";
                Resource[] var10 = var1.getResources(var6);

                for(int var7 = 0; var7 < var10.length; ++var7) {
                    Resource var8 = var10[var7];
                    String var11 = var2.getMetadataReader(var8).getClassMetadata().getClassName();
                    var3.add(var11);
                }
            }
        } catch (Exception var9) {
            new IllegalArgumentException("scan pakcage class error,pakcages:" + var0);
        }

        return var3;
    }

    public static Object getBean(String var0) {
        return getBean(var0, false);
    }

    public static Object getBean(String var0, boolean var1) {
        try {
            return AppUtil.Inner.getContext().getBean(var0);
        } catch (Exception var3) {
            if (var1) {
                logger.error("getBean:" + var0 + "," + var3.getMessage(), var3);
            }

            return null;
        }
    }

    public static <T> T getBean(Class<T> var0) {
        return getBean(var0, false);
    }

    public static <T> T getBean(Class<T> var0, boolean var1) {
        try {
            return AppUtil.Inner.getContext().getBean(var0);
        } catch (Exception var3) {
            if (var1) {
                logger.error("getBean:" + var0 + "," + var3.getMessage(), var3);
            }

            return null;
        }
    }


    public static void publishEvent(ApplicationEvent var0) {
        AppUtil.Inner.getContext().publishEvent(var0);
    }

    private static class Inner {
        private static ApplicationContext context;

        private Inner() {
        }

        public static ApplicationContext getContext() {
            return context;
        }

        public static void setContext(ApplicationContext var0) {
            context = var0;
        }
    }
}

